package com.sjz.DataAsyncLoad.adapter;

import java.io.File;
import java.util.List;

import android.content.Context;
import android.net.Uri;
import android.os.AsyncTask;
import android.os.Handler;
import android.os.Message;
import android.view.LayoutInflater;
import android.view.View;
import android.view.ViewGroup;
import android.widget.BaseAdapter;
import android.widget.ImageView;
import android.widget.TextView;

import com.sjz.DataAsyncLoad.R;
import com.sjz.DataAsyncLoad.domain.Contact;
import com.sjz.DataAsyncLoad.service.ContactService;
/***
 * 自定义适配器
 *
 */
public class ContactAdapter extends BaseAdapter {
	private List<Contact> data;//存储的数据
	private int listviewItem;
	private File cache;
	LayoutInflater layoutInflater; //布局填充服务 
	
	/****
	 * 
	 * @param context  上下文对象
	 * @param data   查询的数据
	 * @param listviewItem  每条数据列表 
	 * @param cache  缓存文件 
	 */
	public ContactAdapter(Context context, List<Contact> data, int listviewItem, File cache) {
		this.data = data;
		this.listviewItem = listviewItem;
		this.cache = cache;
		//通过上下文对象 得到布局填充服务
		layoutInflater = (LayoutInflater) context.getSystemService(Context.LAYOUT_INFLATER_SERVICE);
	}
	/**
	 * 得到数据的总数
	 */
	public int getCount() {
		return data.size();
	}
	/**
	 * 根据数据索引得到集合所对应的数据
	 */
	public Object getItem(int position) {
		return data.get(position);
	}
	
	/****
	 * 数据的id 使用数据的索引
	 */
	public long getItemId(int position) {
		return position;
	}

	/******
	 * 得到每一条数据
	 * position 数据绑定的索引值
	 * convertView  缓存的数据  listview会缓存数据 
	 * parent
	 */
	public View getView(int position, View convertView, ViewGroup parent) {
		ImageView imageView = null;
		TextView textView = null;
		
		if(convertView == null){ //如果没有缓存 
			convertView = layoutInflater.inflate(listviewItem, null);
			imageView = (ImageView) convertView.findViewById(R.id.imageView); //得到图片对象
			textView = (TextView) convertView.findViewById(R.id.textView); //得到文本对象
			//new DataWrapper(imageView, textView))  把数据包装起来
			//setTag 作用是保存对象
			convertView.setTag(new DataWrapper(imageView, textView));
		}else{
			DataWrapper dataWrapper = (DataWrapper) convertView.getTag();//如果有缓存的话，直接取出缓存中的数据
			imageView = dataWrapper.imageView;//得到缓存中的imageView
			textView = dataWrapper.textView;	//得到缓存中的textView
		}
		Contact contact = data.get(position);//从数据中得到数据
		textView.setText(contact.name);  //设置姓名 
		asyncImageLoad(imageView, contact.image);//异步数据加载方式加载图片
		return convertView;
	}
	
	/****
	 * 最终会使用 AsyncTask技术来实现异步加载 和thread的区别是多了一个线程池 可以控制线程的数量
	 * 异步图片加载  
	 * @param imageView    图片对象
	 * @param path   图片路径
	 */
    private void asyncImageLoad(ImageView imageView, String path) {
    	AsyncImageTask asyncImageTask = new AsyncImageTask(imageView);
    	asyncImageTask.execute(path);
		
	}
    
    /***
     * 数据的异步加载  AsyncTask技术
     *String
     *Integer
     *Uri
     */
    private final class AsyncImageTask extends AsyncTask<String, Integer, Uri>{
    	private ImageView imageView;
		public AsyncImageTask(ImageView imageView) {
			this.imageView = imageView;
		}
		protected Uri doInBackground(String... params) {//子线程中执行的
			try {
				//params[0] 路径 cache 缓存的文件
				return ContactService.getImage(params[0], cache);
			} catch (Exception e) {
				e.printStackTrace();
			}
			return null;
		}
		protected void onPostExecute(Uri result) {//运行在主线程
			if(result!=null && imageView!= null)
				imageView.setImageURI(result);
		}	
    }
	/**/
    //异步处理数据  使用的是Thread来启动线程  如果开启线程太多会有问题  
	private void asyncImageLoad2(final ImageView imageView, final String path) {
	//Handler 子线程中不能得到主线程的数据 需要使用hand对象
		final Handler handler = new Handler(){
			public void handleMessage(Message msg) {//运行在主线程中  把主线程中发送数据
				Uri uri = (Uri)msg.obj;
				if(uri!=null && imageView!= null)
					imageView.setImageURI(uri);  //设置图片路径
			}
		};
		
		Runnable runnable = new Runnable() {			
			public void run() {
				try {
					Uri uri = ContactService.getImage(path, cache);//得到图片的uri对象
					//10 id的值 没有用到
					handler.sendMessage(handler.obtainMessage(10, uri));//发送消息  让主线程接收数据
				} catch (Exception e) {
					e.printStackTrace();
				}
			}
		};
		//启动线程
		new Thread(runnable).start();
	}

    /****
     * 数据包装类
     * @author Administrator
     *
     */
	private final class DataWrapper{
		public ImageView imageView;
		public TextView textView;
		public DataWrapper(ImageView imageView, TextView textView) {
			this.imageView = imageView;
			this.textView = textView;
		}
	}
}
